# 拓扑图实现类似xmind收缩效果

# 背景

项目使用G6.js实现

由于拓扑存在各种交叉连线,不能使用提供的树图布局。

现在有需求,收起子节点时动态改变坐标,类似xmind的效果,这里需要手动实现。

# 思路

# 平移全部节点

最先想的是全部重新计算位置比较耗时,所以自己写了个收缩的算法:

当收缩时,在该节点左边的节点加上该节点左边减少的距离,右边同理。更改坐标后,调下g6refreshPositions即可刷新位置了。

实现后发现,当有节点在收缩节点的包围盒里面时,就不知道该怎么收缩了,看了xmindprocessOn,都是不会存在这种情况,所以这种平移的方式在我们的拓扑图中行不通。

# 重新计算位置

# 思路

在收缩后,调用removeItem删除所有子节点,然后再走重新计算位置。

这里为了不改变图的缩放比例,只去修改现有节点的x和y坐标,修改完后,调用positionsAnimate去更新位置,positionsAnimate就是动画版的refreshPositions

同时需要调用updateCombos去更新combo。

渲染完成后,还需触发节点缩放比例对应样式的更新。

# 优化

动态添加删除节点,在子数量几百个的时候就出现了很慢的现象,此方法行不通。

改用显示隐藏的方法代替,获取需要计算坐标的节点是加是否可视的判断。

# 保留手动拖动过的位置

记录相对算法位置的拖动偏移量

dragOffset: {
    x: 1,
    y: 1
}

在未保存位置时,拖动后再去伸缩节点combo,展开时使用此偏移量去做新算法位置的相对偏移。

拖动节点时实时叠加偏移量。

使用保存位置初始化时,使用保存的位置,不需加上偏移量,伸缩时再使用。

这样就解决了保留手动拖动位置与xmind收缩效果的冲突问题。